package com.xiaokaceng.openci.executor;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.openkoala.auth.application.vo.UserVO;
import org.springframework.core.task.TaskExecutor;

import com.xiaokaceng.openci.application.OpenciApplication;
import com.xiaokaceng.openci.domain.CasUserConfiguration;
import com.xiaokaceng.openci.domain.Developer;
import com.xiaokaceng.openci.domain.ProjectDeveloper;

@SuppressWarnings("deprecation")
@Named
public class SyncUserToCasExecutor {

	private static final String CREATE_USER_API = "/api/user";
	private static final String APPLICATION_JSON = "application/json";

	@Inject
	private TaskExecutor taskExecutor;

	@Inject
	private OpenciApplication openciApplication;

	public void execute(ProjectDeveloper projectDeveloper) {
		taskExecutor.execute(new SyncUser(projectDeveloper));
	}

	private class SyncUser implements Runnable {

		private ProjectDeveloper projectDeveloper;
		private HttpClient httpClient;

		public SyncUser(ProjectDeveloper projectDeveloper) {
			this.projectDeveloper = projectDeveloper;
		}

		@Override
		public void run() {
			try {
				httpClient = new DefaultHttpClient();
				HttpPost httpPost = new HttpPost(getCreateUserUrl());
				httpPost.setEntity(createHttpEntity());
				HttpResponse response = httpClient.execute(httpPost);
				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					projectDeveloper.setSyncCas(true);
					return;
				}
				projectDeveloper.setSyncCasFailureCause(getResponseContent(response));
			} catch (Exception e) {
				projectDeveloper.setSyncCasFailureCause(e.toString());
			} finally {
				openciApplication.saveEntity(projectDeveloper);
			}
		}

		private String getResponseContent(HttpResponse response) throws ParseException, IOException {
			HttpEntity httpEntity = response.getEntity();
			return EntityUtils.toString(httpEntity);
		}

		private HttpEntity createHttpEntity() throws UnsupportedEncodingException, JsonProcessingException, IOException {
			StringEntity entity = new StringEntity(toJson(createUser()));
			entity.setContentType(APPLICATION_JSON);
			return entity;
		}

		private String toJson(UserVO user) throws JsonProcessingException, IOException {
			ObjectMapper objectMapper = new ObjectMapper();
			StringWriter writer = new StringWriter();
			JsonGenerator jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(writer);
			jsonGenerator.writeObject(user);
			jsonGenerator.close();
			writer.close();
			return writer.toString();
		}

		private UserVO createUser() {
			Developer developer = projectDeveloper.getDeveloper();
			UserVO userVO = new UserVO();
			userVO.setName(developer.getName());
			userVO.setUserAccount(developer.getDeveloperId());
			userVO.setUserPassword(developer.getPassword());
			userVO.setEmail(developer.getEmail());
			return userVO;
		}

		private String getCreateUserUrl() {
			CasUserConfiguration casUserConfiguration = CasUserConfiguration.getUniqueInstance();
			return casUserConfiguration.getServiceUrl() + CREATE_USER_API;
		}

	}
}
